package aftersale

import (
	"context"
	"fmt"
	"strconv"
	"strings"

	"mall/common/modelx"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	"mall/service/order/model"
	"mall/service/order/rpc/internal/svc"
	"mall/service/order/rpc/types/order"

	"github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type GetAfterSaleByIdLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetAfterSaleByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAfterSaleByIdLogic {
	return &GetAfterSaleByIdLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetAfterSaleByIdLogic) GetAfterSaleById(in *order.BaseIdReq) (*order.AfterSaleResp, error) {
	// logrus.Info(fmt.Sprintf("GetAfterSaleById BaseIdReq: %+v", in))

	if (in.Filter == nil || len(strings.TrimSpace(*in.Filter)) == 0) && (in.Id == nil || *in.Id == 0) {
		return nil, resultx.StatusError(resultx.AFTER_SALE_PARAM_INVALID, "")
	}

	preloadMap, _ := modelx.ParsePreloadAndEagerLoad(in.Preload, in.EagerLoad)
	// logrus.Info(fmt.Sprintf("GetUserAddressById preloadMap: %+v", preloadMap))
	//

	resp := &order.AfterSaleResp{}

	afterSaleRequestEntityName := model.RpcEntityNames.AfterSaleRequest
	if _, ok := model.RpcEntityPreloadMap[afterSaleRequestEntityName]; !ok {
		return resp, nil
	}

	afterSaleRequestRepositoryName := model.RepositoryNames.AfterSaleRequest
	columnMap, ok := model.RepositoryPreloadMap[afterSaleRequestRepositoryName]
	if !ok {
		return resp, nil
	}

	var afterSale *model.AfterSaleRequest
	if in.Id != nil && *in.Id > 0 {
		data, err := l.svcCtx.AfterSaleRequest.FindOne(l.ctx, *in.Id)
		if err != nil {
			return nil, err
		}
		afterSale = data
	} else {
		var selectCols []string
		if preloadFields, ok := preloadMap[afterSaleRequestEntityName]; ok {
			selectCols = modelx.ParseSelectColumns(preloadFields, columnMap)
		}

		filterMap := modelx.ParseFilter(in.Filter, columnMap)
		logrus.Info(fmt.Sprintf("GetAfterSaleById filterMap: %+v", filterMap))
		//
		if filterMap == nil {
			return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
		}

		orderBy := modelx.ParseSorter(in.Sorter, columnMap)
		logrus.Info(fmt.Sprintf("GetAfterSaleById orderBy: %s", orderBy))
		//

		if len(orderBy) == 0 {
			orderBy = model.AfterSaleRequestColumns.CreatedAt + " DESC"
		}

		res, _, err := l.svcCtx.AfterSaleRequest.GetList(l.ctx, model.M{
			"pageSize": uint64(1),
			"orderBy":  orderBy,
			"select":   strings.Join(selectCols, ","),
		}, -1, filterMap)
		if err != nil {
			return nil, err
		}
		if len(res) == 0 {
			return resp, nil
		}
		afterSale = res[0]
	}

	if afterSale == nil {
		return resp, nil
	}

	if in.VisitorId != nil && *in.VisitorId != afterSale.UserID {
		return resp, nil
	}
	//查询地址  是否有地址  有：用指定地址  无：用默认地址
	if afterSale.WithAddress > 0 {
		resp.AddressInfo = l.GetCompanyAddress(afterSale.ReturnAddressID)
	}
	resp.Info = &order.AfterSaleInfo{
		Id:               &afterSale.ID,
		AfterSaleSn:      &afterSale.AfterSalesSN,
		OrderId:          &afterSale.OrderID,
		OrderItemId:      &afterSale.OrderItemID,
		OrderSn:          &afterSale.OrderSN,
		ProductId:        &afterSale.ProductID,
		ProductCode:      &afterSale.ProductCode,
		ProductSkuId:     &afterSale.ProductSkuID,
		ProductSkuCode:   &afterSale.ProductSkuCode,
		ProductSku:       &afterSale.ProductSku,
		SkuThumbUrl:      &afterSale.SkuImageURL,
		ProductTitle:     &afterSale.ProductTitle,
		ProductPrice:     &afterSale.ProductPrice,
		Quantity:         pointy.GetPointer(uint32(afterSale.Quantity)),
		UserId:           &afterSale.UserID,
		NickName:         &afterSale.NickName,
		Mobile:           &afterSale.Mobile,
		ReturnAddressId:  &afterSale.ReturnAddressID,
		AfterSaleType:    pointy.GetPointer(uint32(afterSale.AfterSaleType)),
		RefundType:       pointy.GetPointer(uint32(afterSale.RefundType)),
		ReturnType:       pointy.GetPointer(uint32(afterSale.ReturnType)),
		RefundAmount:     pointy.GetPointer(strconv.Itoa(int(afterSale.RefundAmount))),
		RefundDetails:    pointy.GetPointer(modelx.FormatNullDotString(afterSale.RefundDetails)),
		Remark:           pointy.GetPointer(modelx.FormatNullDotString(afterSale.Remark)),
		ExpressSn:        &afterSale.ExpressSN,
		ReasonForRefusal: &afterSale.ReasonForRefusal,
		Status:           pointy.GetPointer(uint32(afterSale.Status)),
		ProcessTime:      pointy.GetPointer(modelx.FormatNullDotTime(afterSale.ProcessTime, "")),
		CreatedAt:        pointy.GetPointer(modelx.FormatTime(afterSale.CreatedAt, "")),
		UpdatedAt:        pointy.GetPointer(modelx.FormatTime(afterSale.UpdatedAt, "")),
		DeletedAt:        pointy.GetPointer(modelx.FormatNullDotTime(afterSale.DeletedAt, "")),
	}

	return resp, nil
}

func (l *GetAfterSaleByIdLogic) GetCompanyAddress(addressId uint64) *order.CompanyAddressInfo {
	var addressInfo = &order.CompanyAddressInfo{}
	//赋值
	var b = func(res *model.CompanyAddress) {
		*addressInfo = order.CompanyAddressInfo{
			Id:             pointy.GetPointer(res.ID),
			AddressDetails: pointy.GetPointer(res.AddressDetails),
			ContactPerson:  pointy.GetPointer(res.ContactPerson),
			Mobile:         pointy.GetPointer(res.Mobile),
			IsDefault:      pointy.GetPointer(uint64(res.IsDefault)),
			Status:         pointy.GetPointer(uint64(res.Status)),
			DelStatus:      pointy.GetPointer(uint64(res.DelStatus)),
			CreatedAt:      pointy.GetPointer(modelx.FormatTime(res.CreatedAt, "")),
			UpdatedAt:      pointy.GetPointer(modelx.FormatTime(res.UpdatedAt, "")),
			DeletedAt:      pointy.GetPointer(modelx.FormatNullDotTime(res.DeletedAt, "")),
		}
	}
	if addressId > 0 {
		res, err := l.svcCtx.CompanyAddress.FindOneNoCache(l.ctx, nil, addressId)
		if err != nil {
			return nil
		}
		b(res)
		return addressInfo
	}

	filterMap := make(map[string]map[string][]any)
	filterMap[model.CompanyAddressColumns.IsDefault] = map[string][]any{
		"equalTo": {1},
	}

	addressList, _, err := l.svcCtx.CompanyAddress.GetList(l.ctx, model.M{}, -1, filterMap)
	if err != nil {
		return nil
	}
	if len(addressList) == 0 {
		return nil
	}
	b(addressList[0])

	return addressInfo
}
